/**
 * Copyright 2018-2020 stylefeng & fengshuonan (sn93@qq.com)
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.stylefeng.roses.core.base.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.guns.core.shiro.ShiroKit;
import cn.stylefeng.guns.core.shiro.ShiroUser;
import cn.stylefeng.roses.core.base.warpper.BaseControllerWrapper;
import cn.stylefeng.roses.core.reqres.response.SuccessResponseData;
import cn.stylefeng.roses.core.util.HttpContext;
import cn.stylefeng.roses.kernel.model.exception.ServiceException;
import cn.stylefeng.roses.kernel.model.exception.enums.CoreExceptionEnum;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.Objects;

/**
 * 控制器基类，封装一些控制器常用的方法
 *
 * @author fengshuonan
 * @Date 2018/7/23 下午3:45
 */
public class BaseController {

    protected final String REDIRECT = "redirect:";
    protected final String FORWARD = "forward:";

    protected static SuccessResponseData SUCCESS_TIP = new SuccessResponseData();

    protected HttpServletRequest getHttpServletRequest() {
        return HttpContext.getRequest();
    }

    protected HttpServletResponse getHttpServletResponse() {
        return HttpContext.getResponse();
    }

    protected HttpSession getSession() {
        return Objects.requireNonNull(HttpContext.getRequest()).getSession();
    }

    protected HttpSession getSession(Boolean flag) {
        return Objects.requireNonNull(HttpContext.getRequest()).getSession(flag);
    }

    protected String getPara(String name) {
        return Objects.requireNonNull(HttpContext.getRequest()).getParameter(name);
    }

    protected void setAttr(String name, Object value) {
        Objects.requireNonNull(HttpContext.getRequest()).setAttribute(name, value);
    }

    /**
     * 包装一个list，让list增加额外属性
     */
    protected Object warpObject(BaseControllerWrapper warpper) {
        return warpper.wrap();
    }

    /**
     * 删除cookie
     */
    protected void deleteCookieByName(String cookieName) {
        Cookie[] cookies = this.getHttpServletRequest().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals(cookieName)) {
                Cookie temp = new Cookie(cookie.getName(), "");
                temp.setMaxAge(0);
                this.getHttpServletResponse().addCookie(temp);
            }
        }
    }

    /**
     * 删除所有cookie
     */
    protected void deleteAllCookie() {
        Cookie[] cookies = this.getHttpServletRequest().getCookies();
        for (Cookie cookie : cookies) {
            Cookie temp = new Cookie(cookie.getName(), "");
            temp.setMaxAge(0);
            this.getHttpServletResponse().addCookie(temp);
        }
    }

    /**
     * 返回前台文件流
     *
     * @author fengshuonan
     * @date 2017年2月28日 下午2:53:19
     */
    protected ResponseEntity<InputStreamResource> renderFile(String fileName, String filePath) {
        try {
            final FileInputStream inputStream = new FileInputStream(filePath);
            return renderFile(fileName, inputStream);
        } catch (FileNotFoundException e) {
            throw new ServiceException(CoreExceptionEnum.FILE_READING_ERROR);
        }
    }

    /**
     * 返回前台文件流
     *
     * @author fengshuonan
     * @date 2017年2月28日 下午2:53:19
     */
    protected ResponseEntity<InputStreamResource> renderFile(String fileName, byte[] fileBytes) {
        return renderFile(fileName, new ByteArrayInputStream(fileBytes));
    }

    /**
     * 返回前台文件流
     *
     * @param fileName    文件名
     * @param inputStream 输入流
     * @return
     * @author 0x0001
     */
    protected ResponseEntity<InputStreamResource> renderFile(String fileName, InputStream inputStream) {
        InputStreamResource resource = new InputStreamResource(inputStream);
        String dfileName = null;
        try {
            dfileName = new String(fileName.getBytes("gb2312"), "iso8859-1");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", dfileName);
        return new ResponseEntity<>(resource, headers, HttpStatus.CREATED);
    }

    /**
     * 将对象赋值
     * id  delFlag  createUserId updateUserId createUserName updateUserName createDate updateDate
     *
     * @param
     * @return
     * @Author dusd
     * @Date 2019/4/27 12:16
     */
    protected void initInsertObject(Object object) {
        try {
            if (object == null)
                return;
            //当前登录信息
            ShiroUser shiroUser = ShiroKit.getUser();
            if (shiroUser == null)
                return;
            String userId = shiroUser.getId().toString();
            String account = shiroUser.getAccount();
            Field[] arrField = object.getClass().getDeclaredFields();
            Date nowDate = new Date();
            for (Field field : arrField) {
                //字段名称
                String fieldName = field.getName();
                field.setAccessible(true);

                switch (fieldName) {
                    case "id": {
                        if (field.get(object) == null || StrUtil.isBlank(field.get(object).toString())) {
                            field.set(object, RandomUtil.simpleUUID());
                        }
                        break;
                    }
                    case "delFlag": {
                        field.set(object, "N");
                        break;
                    }
                    case "createUserId": {
                        field.set(object, userId);
                        break;
                    }
                    case "updateUserId": {
                        field.set(object, userId);
                        break;
                    }
                    case "createUserName": {
                        field.set(object, account);
                        break;
                    }
                    case "updateUserName": {
                        field.set(object, account);
                        break;
                    }
                    case "createDate": {
                        field.set(object, nowDate);
                        break;
                    }
                    case "updateDate": {
                        field.set(object, nowDate);
                        break;
                    }
                    case "status": {
                        field.set(object, "ENABLE");
                        break;
                    }
                    default: {
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 将对象赋值
     * updateUserId updateUserName updateDate
     *
     * @param
     * @return
     * @Author dusd
     * @Date 2019/4/27 12:16
     */
    protected void initUpdateObject(Object object) {
        try {
            if (object == null)
                return;
            //当前登录信息
            ShiroUser shiroUser = ShiroKit.getUser();
            if (shiroUser == null)
                return;
            String userId = shiroUser.getId().toString();
            String account = shiroUser.getAccount();
            Field[] arrField = object.getClass().getDeclaredFields();
            Date nowDate = new Date();
            for (Field field : arrField) {
                //字段名称
                String fieldName = field.getName();
                field.setAccessible(true);

                switch (fieldName) {
                    case "updateUserId": {
                        field.set(object, userId);
                        break;
                    }
                    case "updateUserName": {
                        field.set(object, account);
                        break;
                    }
                    case "updateDate": {
                        field.set(object, nowDate);
                        break;
                    }
                    default: {
                        break;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
